#include <pthread.h>
#include <wiringPi.h>
#include <stdio.h>

#include "control.h"
#include "smoke_interface.h"
#include "msg_queue.h"
#include "global.h"

//定义烟雾传感器连接的引脚及模式
#define SMOKE_PIN 6
#define SMOKE_MODE INPUT

//初始化烟雾传感器
static int smoke_init(void)
{
    printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
    pinMode(SMOKE_PIN, SMOKE_MODE);

    return 0;
}

//清理资源函数
static void smoke_final(void)
{
    //do nothing;
}

//获取烟雾传感器数据并发送到消息队列
static void* smoke_get(void *arg)
{
    int status = HIGH;  //当前传感器状态，默认高电平
    int switch_status = 0;  //记录报警状态是否已触发
    unsigned char buffer[6] = {0xAA, 0x55, 0x00, 0x00, 0x55, 0xAA};//发送缓冲区
    ssize_t byte_send = -1; //发送字节数记录
    mqd_t mqd = -1;     //消息队列描述符
    ctrl_info_t *ctrl_info = NULL;  //控制信息结构图指针

    if (NULL != arg)
        ctrl_info = (ctrl_info_t *)arg;

    if(NULL != ctrl_info)
    {
        mqd = ctrl_info->mqd;
    } 
    if ((mqd_t)-1 == mqd)
    {
        pthread_exit(0);    //如果消息队列无效则退出线程
    }
    
    pthread_detach(pthread_self());//分离线程，使其结束后自动回收资源
    printf("%s thread start\n", __func__);  //打印线程启动信息

    while(1)    //循环检测传感器状态
    {
        status = digitalRead(SMOKE_PIN);//读取传感器状态

        if(LOW == status)   //检测到烟雾（低电平表示有烟雾）
        {
            buffer[2] = 0x45;   //命令码：烟雾警报
            buffer[3] = 0x00;   //参数：触发警报
            switch_status = 1;  //更新报警状态

            //打印发送的数据内容
            printf("%s|%s|%d:send 0x%x, 0x%x,0x%x, 0x%x, 0x%x,0x%x\n",
                   __FILE__, __func__, __LINE__, 
            buffer[0], buffer[1], buffer[2], buffer[3], buffer[4],buffer[5]);
            
            byte_send = mq_send(mqd, buffer, 6, 0);//将警报消息发送至消息队列
            if(-1 == byte_send)
            {
                continue;   //发送失败则继续下一次循环
            }
        }
        else if(HIGH == status && 1 == switch_status)//烟雾消失且之前处于报警状态
        {
            buffer[2] = 0x45;   //命令码：烟雾警报解除
            buffer[3] = 0x01;   //参数：取消警报
            switch_status = 0;  //更新报警状态

            //打印发送的数据内存
            printf("%s|%s|%d:send 0x%x, 0x%x,0x%x, 0x%x, 0x%x,0x%x\n", 
                __FILE__, __func__, __LINE__, 
            buffer[0], buffer[1], buffer[2], buffer[3],buffer[4],buffer[5]);        
            
            byte_send = mq_send(mqd, buffer, 6, 0);//将取消警报消息发送至消息队列
            if(-1 == byte_send){
                continue;   //发送失败则继续下一次循环
            }
        }
        sleep(5);//没隔5s检测一次
    }

    pthread_exit(0);    //线程正常退出
}

//定义烟雾传感器控制模块实例
struct control smoke_control = {
    .control_name = "smoke",    //烟雾传感器模块名称
    .init = smoke_init,         //初始化函数
    .final = smoke_final,       //结束函数
    .get = smoke_get,           //数据接收函数（线程主函数）
    .set = NULL,                //设置函数（未使用）
    .next = NULL                //链表指针
};  

//将烟雾传感器控制模块添加到全局控制链表中
struct control *add_smoke_to_ctrl_list(struct control *phead)
{
    //使用头插法将烟雾传感器控制模块添加到链表中
    return add_interface_to_ctrl_list(phead, &smoke_control);
};